
#ifndef _RFID_H_
#define _RFID_H_
#include "define.h"

#define UID_4 4
#define UID_7 7
#define UID_10 10

#define PICC_CID 0x00 // 0~14 随意指定

//卡片上电状态定义
#define PDU_POWER_OFF    0
#define PDU_POWER_ON     1

//pdu指令协议类型定义
#define PDU_TYPE_T0      0
#define PDU_TYPE_T1      1

#define T1_FRAME_A       (0x0A)
#define T1_FRAME_B       (0x0B)

#define ISO14443_B_CID_1       1
#define ATQB_LEN               12

#define ISO14443_P3       1
#define ISO14443_P4       2

#define RF_NONE_CARD            0       //RF通道中没有卡片
#define ISO14443_A              1       //A卡
#define ISO14443_B              2       //B卡
#define RF_TYPE_FELICA          3
#define RF_TYPE_MF              4
#define ISO15693                5
#define RF_TYPE_UL              6
#define RF_TYPE_DF              7
#define SRI512                  8
#define RF_TYPE_MF_MORE         9      //检测到多张M1卡
#define RF_TYPE_T1T             10
#define RF_TYPE_P2P             11     //P2P
#define RF_125K_ID              12     //ID卡

//ATQB-应用数据
typedef struct _B_APP_DATA_DEF {
    uint8_t AFI;
    uint8_t CRC_B_0;
    uint8_t CRC_B_1;
    uint8_t APP_number;
}B_APP_DATA_DEF;

//ATQB-协议信息
typedef struct _B_PROTOCOL_INF_DEF {
    uint8_t  bps;               //位速率能力

    uint8_t  protocol_type:4;   //协议类型
    uint8_t  max_frame_len:4;   //最大帧长度

    uint8_t  FO:2;              //帧选项
    uint8_t  _ADC:2;             //应用数据编码定义
    uint8_t  FWI:4;             //帧等待时间整数
}PROTOCOL_INF_DEF;

//ATQB
typedef struct _ATQB_DATA_DEF {
    uint8_t           start_f;   //起始帧
    uint8_t           PUPI[4];   //4位PUPI
    B_APP_DATA_DEF    app_data;  //应用数据
    PROTOCOL_INF_DEF  INF;       //协议信息
}ATQB_DATA_DEF;

//ATQB-union
typedef union _ATQB_UNION_DEF {
    uint8_t        ATQB_str[ATQB_LEN];
    ATQB_DATA_DEF  ATQB;
}ATQB_UNION_DEF;

typedef struct _PDU_STATUS_DEF {
    uint8_t  power;
    uint8_t  pdu_type;
    uint8_t  protocol;
    uint8_t  protocolLayer;  //ISO14443协议层数ISO14443_P3/ISO14443_P4
    uint8_t  last_fh;        //在T1协议中，帧头在0x0A和0x0B之间交替变换
    uint8_t  dataSendFlag;   //是否真正发送数据
}PDU_STATUS_DEF;

typedef struct tag_info
{
    u8 uncoded_key_is_a:1;
    u8 opt_step;
    u8 uid_length;
    u8 tag_type;
    u8 tag_type_bytes[2];
    u8 serial_num[8];
    u8 uncoded_key[6];
    struct block {
        u8 num;
        u8 block_data[16];
    } block;
} tag_info;

typedef struct statistics_t
{
    u32 reqa_cnt;
    u32 reqa_fail;
    u32 cosa_cnt;
    u32 cosa_fail;

    u32 reqb_cnt;
    u32 reqb_fail;
    u32 cosb_cnt;
    u32 cosb_fail;

    u32 felica_cnt;
    u32 felica_fail;

    u32 inv_cnt;
    u32 inv_fail;
    u32 inv_check_fail;
    u32 inv_write_fail;
  
  
    
    u32 m1_cnt;
    u32 m1_fail;


    u32 authenticate_fail;

    u32 lpcd_cnt;
    u32 lpcd_fail;


} statistics_t;


typedef struct lpcd_config_s
{
    u32     delta;
    u32     t_inactivity_ms;  //休眠时间
    u32     skip_times;        //跳过时间
    u8      skip_cnt;
    u32     t_detect_us;
    u8      g_lpcd_config_test_start;
    u32     detect_way;
    u8      card_to_enter;
    u8      PICC_CFG;
} lpcd_config_t;



typedef struct polling_15693_s
{
  u8        blocknum;
  u8        blocksize;
  u8        flag;
  
  
} polling_15693_s;

typedef struct {
    uint8_t head[2];
    uint8_t TotalLen;
    uint8_t seidCode;
    uint8_t seidLen;
    uint8_t seidData[32];
}SeidRespApduDef;

/*读卡和标签工作模式定义 */
typedef enum{
    MODE_PCD_PICC_COEXIST = 0,//共存
    MODE_PCD_ONLY,//读卡
    MODE_PICC_ONLY,//标签
}WORK_MODE_DEF;

extern statistics_t g_statistics;
extern u8 g_statistic_refreshed;

extern tag_info g_tag_info;
extern u32   g_cos_loop_times;//extern u32 g_cos_loop_times;
extern u8 g_loop_buf[60];
extern u8 g_cos_loop;
extern U8 OperateState;
extern u8 g_auto_read_write;
extern u8 g_auto_read_typeB_id;
extern u32  g_cos_loop_times;


void init_rfid(void);
void card_operation(u8 *pcmd);
char com_reqa(u8 *pcmd);
char com_reqb(u8 *pcmd);
int com_typeb_attrib(void);
void statistic_print(void);
void statistic_cleared(void);
void com_exchange(u8 * pcmd);
int com_reqc(u8 *pcmd);
u8 com_iso15693_inventory(u8 *pcmd);
void rfid_cmd_process(void *pkt);
int com_inventory(u8 *pcmd);
void rfid_task(void);
void com_mf1_value_block(u8 *pcmd);



/*lpcd*/
void pcd_lpcd_config_start(lpcd_config_t lpcd_config);
void pcd_lpcd_end(void);
u8   pcd_lpcd_check(void);
void g_lpcd_init(void);



#endif
